#include <stdio.h>
#include <stdlib.h>

typedef int *Integer;

void secondPointer(Integer *i)
{
    // Integer *i = &f; // 实参是内存地址，那么获取f变量的值 *i
    printf("Method==>v=%p, vp=%p, pp=%p\n", *i, i, &i);
}

int main()
{
    int a = 20;
    // int *b = &b; // 方式①写法. 指针变量初始化时，不能把具体赋给指针(类型不匹配)
    int *b; // 方式②写法， 声明一个类型int *的指针变量b
    b = &a; // 指针变量的值是变量a的内存地址。(&取址运算符，将a的内存地址分配给b)
    *b = a; // 指针指向的内存地址所存放的数据是变量a的值。 (*解引用运算符，将a的值分配给b所指向的内存地址)

    // int **c = &b;  // 定义二级指针
    int **c;
    c = &b;
    *c = b;
    int *w = b; // 指针变量w指向 指针变量b指向的地址. (即指针变量w的值是变量a的地址)
    // int *w; w = b;
    Integer d = &a;  // 等同 b=&a;
    Integer *e = &b; // 等同 c=&b;

    // &a 取int类型变量a的内存地址
    printf("A==>v=%d, vp=%p\n", a, &a);
    // *b 取int *类型变量b指向的内容;   &b取int *类型变量b的内存地址
    printf("B==>v=%d, vp=%p, pp=%p\n", *b, b, &b);
    printf("W==>v=%d, vp=%p, pp=%p\n", *w, w, &w);
    // b 是 int * 指针变量，根据优先级等同 &(*b)=&a 取值的地址 、*(&b) 取地址的值(地址里的值是地址)
    // printf("ExtendB>>vp=%p, pp=%p\n\n", &*b, *&b); // &*b 等于 *&b 等于 b

    // *(*c) 详解: *c 访问的是指针指向b地址存放的数据, *(*c) 访问的是指针指向a地址存放的数据
    printf("C==>v=%d, vp=%p, pp=%p\n", *(*c), c, &c);
    // printf("+++++>vp=%p, pp=%p, %p\n", *(&c), &(*c), &**c);
    printf("\n");
    printf("D==>v=%d, vp=%p, pp=%p\n", *d, d, &d);
    printf("E==>v=%d, vp=%p, pp=%p\n", *(*e), e, &e);

    // 分配内存
    Integer f = (int *)malloc(sizeof(int));
    // 地址传递
    secondPointer(&f);
    return 0;
}

/**
A==>v=1, vp=0x7ffeefbff258
B==>v=1, vp=0x7ffeefbff258, pp=0x7ffeefbff250
C==>v=1, vp=0x7ffeefbff250, pp=0x7ffeefbff248

D==>v=1, vp=0x7ffeefbff258, pp=0x7ffeefbff240
E==>v=1, vp=0x7ffeefbff250, pp=0x7ffeefbff238
Method==>v=0x1006040c0, vp=0x7ffeefbff230, pp=0x7ffeefbff218
*/